﻿using JuCheap.Core.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JuCheap.Core.IRepository
{
    /// <summary>
    /// 仓储接口
    /// </summary>
    /// <typeparam name="TEntity">实体类型</typeparam>
    public interface IRepositoryBase<TEntity> where TEntity : class, new()
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        Task<string> InsertAsync(TEntity entity);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="list">实体集合</param>
        Task BatchInsertAsync(List<TEntity> list);

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="properties">需要更新字段的表达式(可以不指定，默认全部更新)</param>
        /// <returns></returns>
        Task UpdateAsync(TEntity entity, params Expression<Func<TEntity, object>>[] properties);

        /// <summary>
        /// 删除指定主键的数据(逻辑删除)
        /// </summary>
        /// <param name="keyId">主键Id</param>
        /// <returns></returns>
        Task DeleteAsync(string keyId);

        /// <summary>
        /// 批量删除(逻辑删除)
        /// </summary>
        /// <param name="keyIds">主键Id集合</param>
        /// <returns></returns>
        Task DeleteAsync(IList<string> keyIds);

        /// <summary>
        /// 根据条件删除实体(物理删除)
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 根据主键查询实体，如果不存在，则抛出异常
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <returns></returns>
        Task<TEntity> FindAsync(object keyValue);

        /// <summary>
        /// 根据条件查询实体，不存在返回null
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 根据条件判断是否存在相同的数据
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="filter">分页条件</param>
        /// <param name="predicate">查询过滤条件</param>
        /// <returns></returns>
        Task<PagedResult<TEntity>> QueryPagesAsync(BaseCondition filter, Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Queryable(自动加上CompanyId过滤参数,默认为true)
        /// </summary>
        /// <param name="enableCompanyFilter">是否自动加上公司Id过滤参数(默认为true)</param>
        /// <returns></returns>
        IQueryable<TEntity> Queryable(bool enableCompanyFilter = true);
    }
}
